package com.yuneec.droneservice;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;

import com.yuneec.droneservice.model.HardwareEvent;
import com.yuneec.droneservice.parse.DroneFeedback;
import com.yuneec.droneservice.protocol.ProtocolPlugin;
import com.yuneec.droneservice.protocol.analysis.CameraStreamReceiver;
import com.yuneec.droneservice.protocol.analysis.IMessageReceiver;
import com.yuneec.droneservice.protocol.analysis.MediaStreamReceiver;
import com.yuneec.droneservice.request.IRequest;
import com.yuneec.droneservice.request.OnListener;
import com.yuneec.droneservice.request.OnRequestListener;

/**
 * Created by jw.gu on 2016/7/18.
 */
public class ServiceManager {
    private DroneService.DroneBinder droneBinder = null;
    private static ServiceManager instance;
    protected boolean mIsBinded = false;
    private Context context;
    private InitCompleteListener initCompleteListener;
    private ProtocolPlugin protocolPlugin;

    public interface InitCompleteListener {
        void onInitComplete();
    }

    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            mIsBinded = true;
            droneBinder = (DroneService.DroneBinder) service;
            droneBinder.init(context);
            if (null != initCompleteListener) {
                initCompleteListener.onInitComplete();
            }
        }

        public void onServiceDisconnected(ComponentName className) {
            mIsBinded = false;
        }
    };

    public void init(Context context, InitCompleteListener initCompleteListener) {
        if (this.context != null) {
            return;
        }
        mIsBinded = false;
        this.context = context;
        this.initCompleteListener = initCompleteListener;
        Intent serviceIntent = new Intent(context, com.yuneec.droneservice.DroneService.class);
        context.bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);
    }

    public void unInit() {
        if (droneBinder != null) {
            droneBinder.deinit(context);
        }
        if (mIsBinded) {
            context.unbindService(mConnection);
            mIsBinded = false;
        }
        initCompleteListener = null;
        droneBinder = null;
        context = null;
    }

    /**
     * AOA消息的解析协议
     * OB-MavLink2: com.yuneec.mavlink.MavLinkProtocolPlugin
     * FB-lcm:      com.yuneec.droneservice.RCProtocolPlugin
     *
     * @param plugin
     */
    public void useProtocolPlugin(ProtocolPlugin plugin) {
        this.protocolPlugin = plugin;
    }

    public void removeProtocolPlugin() {
        this.protocolPlugin = null;
    }


    public ProtocolPlugin getProtocolPlugin() {
        return this.protocolPlugin;
    }

    private ServiceManager() {
        instance = this;
    }

    public static ServiceManager getInstance() {
        if (instance == null) {
            synchronized (ServiceManager.class) {
                if (instance == null) {
                    instance = new ServiceManager();
                }
            }
        }
        return instance;
    }

    /**
     * 遥控器主动上报的消息监听操作
     */
    public void clearControllerFeedbackListener() {
        clearListener(OnListener.L_CONTROLLER_FEEDBACK);
    }

    public void addControllerFeedbackListener(OnListener<HardwareEvent> listener) {
        addListener(OnListener.L_CONTROLLER_FEEDBACK, listener);
    }

    public void removeControllerFeedbackListener(OnListener<HardwareEvent> listener) {
        removeListener(OnListener.L_CONTROLLER_FEEDBACK, listener);
    }

    /**
     * 飞机的状态消息监听操作
     */
    public void clearDroneFeedbackListener() {
        clearListener(OnListener.L_DRONE_FEEDBACK);
    }

    public void addDroneFeedbackListener(OnListener<DroneFeedback> listener) {
        addListener(OnListener.L_DRONE_FEEDBACK, listener);
    }

    public void removeDroneFeedbackListener(OnListener<DroneFeedback> listener) {
        removeListener(OnListener.L_DRONE_FEEDBACK, listener);
    }

    /**
     * 2.4g透传的消息监听操作
     */
    public void clearPayloadByPassListener() {
        clearListener(OnListener.L_PAYLOAD_BY_PASS);
    }

    public void addPayloadByPassListener(OnListener<byte[]> listener) {
        addListener(OnListener.L_PAYLOAD_BY_PASS, listener);
    }

    public void removePayloadByPassListener(OnListener<byte[]> listener) {
        removeListener(OnListener.L_PAYLOAD_BY_PASS, listener);
    }

    /**
     * 注册一些特殊消息的监听
     *
     * @param id 消息的分类ID  可以在OnListener中找到常量  特殊的可在对应的ProtocolPlugin中找到
     */
    public void clearListener(int id) {
        if (droneBinder != null) {
            droneBinder.clearListener(id);
        }
    }

    public void addListener(int id, OnListener<?> listener) {
        if (droneBinder != null) {
            droneBinder.registerListener(id, listener);
        }
    }

    public void removeListener(int id, OnListener<?> listener) {
        if (droneBinder != null) {
            droneBinder.unregisterListener(id, listener);
        }
    }

    /**
     * 监听AOA连接状态的Callback
     */
    public void clearConnectionListener() {
        if (droneBinder != null) {
            droneBinder.clearConnectionListener();
        }
    }

    public boolean isConnected() {
        if (droneBinder != null) {
            return droneBinder.isConnected();
        }else {
            return false;
        }
    }

    public boolean addConnectionListener(ConnectionListener connectionListener) {
        if (droneBinder != null) {
            droneBinder.registerConnectionListener(connectionListener);
            return true;
        }else {
            return false;
        }
    }

    public boolean removeConnectionListener(ConnectionListener connectionListener) {
        if (droneBinder != null) {
            droneBinder.unregisterConnectionListener(connectionListener);
            return true;
        }else {
            return false;
        }
    }


    /**
     * 向AOA通道写数据
     *
     * @param id  通道ID
     * @param buf 发送数据
     * @return
     */
    public int writeAOADataBlock(int id, byte[] buf) {
        if (droneBinder != null) {
            return droneBinder.writeAOADataBlock(id, buf);
        }
        return -1;
    }

    public void writeAOAData(int id, byte[] buf) {
        if (droneBinder != null) {
            droneBinder.writeAOAData(id, buf);
        }
    }

    /**
     * 发送遥控器指令
     *
     * @param req      所有支持的指令在com.yuneec.droneservice.command包下
     * @param listener 返回监听
     */
    public void sendDroneCommand(IRequest req, OnRequestListener listener) {
        if (droneBinder != null) {
            droneBinder.asyncSendCommand(req, listener);
        }
    }

    /**
     * 操作AOA通道数据
     * 注：
     * 554      视频流
     * 9528     相机流
     * 1108     火鸟的指令流
     * 10011    OB的指令流
     * (1108和10011如果自己监听的话，指令的发送返回需要自己实现，sendDroneCommand(IRequest,OnRequestListener)失效!)
     *
     * @param receiver
     */
    public void registStreamReceive(IMessageReceiver receiver) {
        if (droneBinder != null) {
            droneBinder.registStreamReceive(receiver);
        }
    }

    public void unregistStreamReceive(IMessageReceiver receiver) {
        if (droneBinder != null) {
            droneBinder.unregistStreamReceive(receiver);
        }
    }

    public void unregistStreamReceive(int portId) {
        if (droneBinder != null) {
            droneBinder.unregistStreamReceive(portId);
        }
    }

    /**
     * 视频流监听    通道554
     *
     * @param receiver
     */
    public void setMediaStreamReceiver(MediaStreamReceiver receiver) {
        if (droneBinder != null) {
            droneBinder.setMediaStreamReceiver(receiver);
        }
    }

    /**
     * 相机流监听    通道9528
     *
     * @param receiver
     */
    public void setCameraStreamReceiver(CameraStreamReceiver receiver) {
        if (droneBinder != null) {
            droneBinder.setCameraStreamReceiver(receiver);
        }
    }

}
